package com.igeek.health.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.igeek.health.entity.Menu;
import com.igeek.health.mapper.MenuMapper;
import com.igeek.health.service.IMenuService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.igeek.health.vo.MenuVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 *
 * @author fengqq
 * @since 2024-08-26
 *
 * 新增菜单，更新菜单，修改菜单，一定要记得保证数据库和缓存之间的一致性？
 * 思考：先删除数据库再删除缓存？ 先删除缓存再删除数据库？
 * 解决方法：延时双删
 */
@Service
public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements IMenuService {
    @Autowired
    private MenuMapper menuMapper;

    //根据管理员id 查询所有的动态菜单列表 包含二级菜单列表
    @Transactional(readOnly = true)
    //缓存：先根据缓存规则查询redis中是否存在，若不存在则到数据库来查询后，查询后的结果存储到redis中。若存在则直接返回
    @Cacheable(cacheNames = "menu",keyGenerator = "keyGenerator")
    @Override
    public List<MenuVO> findAll(Integer userId) {
        //1.根据管理员id 查看所有的一级菜单
        List<Menu> menusByLevel = menuMapper.selectMenusByUserId(userId, 1);

        List<MenuVO> result = new ArrayList<>();

        //2.遍历根据一级菜单的path 查询对应的二级菜单列表 MenuVO
        menusByLevel.forEach(menu -> {
            List<Map<String, String>> mapList = menuMapper.findByMap(menu.getPath());
            MenuVO first = new MenuVO();
            List<MenuVO> children = new ArrayList<MenuVO>();
            mapList.forEach(map->{
                //封装一级菜单对象
                first.setTitle(map.get("name1"));
                first.setPath(map.get("path1"));
                first.setIcon(map.get("icon1"));

                //封装二级菜单对象
                MenuVO second = new MenuVO();
                second.setTitle(map.get("name2"));
                second.setPath(map.get("path2"));
                second.setLinkUrl(map.get("linkUrl"));
                children.add(second);
            });
            //将一级菜单 和 二级菜单列表 进行关联
            first.setChildren(children);
            //将封装好menuvo 添加到list
            result.add(first);
        });
        return result;
    }
}
